package com.samehope.ar.util;

import com.alibaba.fastjson.JSON;
import com.samehope.ar.weixin.envir.WeiXinProperties;
import com.samehope.ar.weixin.support.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import java.util.HashMap;
import java.util.Map;

/**
 * @Description: 微信公众号帮助类
 * @Author: ZhangLuo
 * @Email: 1946430@qq.com
 */
@Slf4j
@Component
public class WeiXinPublicUtils {

    /**
     * 获取accessToken接口
     */
    private static final String ACCESS_TOKEN_URL = "https://api.weixin.qq.com/cgi-bin/token";
    /**
     * 自定义消息发送接口
     */
    private static final String CUSTOM_MESSAGE_URL = "https://api.weixin.qq.com/cgi-bin/message/custom/send?access_token=";
    /**
     * 获取openId的接口
     */
    private static final String OPENID_URL = "https://api.weixin.qq.com/sns/oauth2/access_token";

    /**
     * 获取用户信息
     */
    private static final String INFO_URL = "https://api.weixin.qq.com/cgi-bin/user/info";

    private static WeiXinProperties properties;

    @Autowired
    private WeiXinProperties weiXinProperties;

    @PostConstruct
    public void init() {
        properties = weiXinProperties;
    }

    /**
     * 获取用户信息
     * @param openId
     * @return
     */
    public static UserInfoResult getUserInfo(String openId) {
        ParaMap pm = ParaMap.create("access_token", getAccessToken()).put("openid", openId).put("lang", "zh_CN");
        String response = HttpUtils.httpGet(INFO_URL, pm.getData());
        UserInfoResult userInfoResult = JSON.parseObject(response, UserInfoResult.class);
        if (userInfoResult.getErrcode() != null) {
            log.error("获取用户信息失败, 失败码: {}, 失败信息: {}", userInfoResult.getErrcode(), userInfoResult.getErrmsg());
            throw new IllegalArgumentException(userInfoResult.getErrmsg());
        }
        return userInfoResult;
    }

    /**
     * 功能描述 设置当前用户openId
     * @author 垠坤-张罗
     * @date 2019-5-7 16:29
     * @param
     * @return void
     */
    public static String getOpenId(String code) {
        Map<String, String> params = new HashMap<>(16);
        params.put("appid", properties.getPublicAppId());
        params.put("secret", properties.getPublicSecretKey());
        params.put("code", code);
        params.put("grant_type", "authorization_code");
        String response = HttpUtils.httpGet(OPENID_URL, params);
        SnsAccessToken snsAccessToken = JSON.parseObject(response, SnsAccessToken.class);
        if (snsAccessToken.getErrcode() != null) {
            log.error("获取openId失败, 失败码: {}, 失败信息: {}", snsAccessToken.getErrcode(), snsAccessToken.getErrmsg());
            throw new IllegalArgumentException(snsAccessToken.getErrmsg());
        };
        return snsAccessToken.getOpenid();
    }

    /**
     * 功能描述 给指定用户发送消息
     * check: https://developers.weixin.qq.com/doc/offiaccount/Message_Management/Service_Center_messages.html
     * @author 垠坤-张罗
     * @date 2019-5-7 16:35
     * @param openId
     * @param message
     * @return boolean
     */
    public static boolean sendMessage(String openId, String message) {
        Map<String, Object> params = new HashMap(16);
        params.put("touser", openId);
        params.put("msgtype", "text");
        Map<String, Object> textObj = new HashMap(16);
        textObj.put("content", message);
        params.put("text", textObj);
        String response = HttpUtils.httpPostSendRequestBody(CUSTOM_MESSAGE_URL + getAccessToken(), params);
        ApiResult apiResult = new ApiResult(response);
        if (apiResult.getErrorCode() != 0) {
            log.error("发送客服消息失败, 失败码: {}, 失败信息: {}", apiResult.getErrorCode(), apiResult.getErrorMsg());
            throw new IllegalArgumentException(apiResult.getErrorMsg());
        }
        return apiResult.isSucceed();
    }


    /**
     * 功能描述 获取accessToken
     * @author 垠坤-张罗
     * @date 2019-5-7 17:48
     * @param
     * @return java.lang.String
     */
    public static String getAccessToken() {
        String accessTokenString = RedisUtil.get("accessToken");
        if (accessTokenString != null) {
            return accessTokenString;
        }
        Map<String, String> params = new HashMap<>(16);
        params.put("appid", properties.getPublicAppId());
        params.put("secret", properties.getPublicSecretKey());
        params.put("grant_type", "client_credential");
        log.info("缓存未命中, 发起Http请求获取AccessToken");
        String response = HttpUtils.httpGet(ACCESS_TOKEN_URL, params);
        AccessToken accessToken = JSON.parseObject(response, AccessToken.class);
        if (accessToken.getErrcode() != null) {
            log.error("获取AccessToken失败, 失败码: {}, 失败信息: {}", accessToken.getErrcode(), accessToken.getErrmsg());
            throw new IllegalArgumentException(accessToken.getErrmsg());
        }
        RedisUtil.set("accessToken", accessToken.getAccess_token(), 7000L);
        return accessToken.getAccess_token();
    }
}
